package com.noc.spring.common.utils;

import javax.servlet.http.HttpServletRequest;

public class IpUtils {
	private IpUtils() {
		
	}

	/**
	 * @Desc 根据ip和子网掩码获取网段
	 * @param ip
	 * @param subnetMask
	 * @return Segment
	 */
	public static String getSegment(String ip, String subnetMask) {
		int sub = maskStr2InetMask(subnetMask);
		int byte4Mask = 0xff000000;
		int byte3Mask = 0x00ff0000;
		int byte2Mask = 0x0000ff00;
		int byte1Mask = 0x000000ff;
		int mask = 0xffffffff;
		int ipMask = mask << (32 - sub);
		int ip1 = (ipMask & byte4Mask) >>> 24;
		int ip2 = (ipMask & byte3Mask) >>> 16;
		int ip3 = (ipMask & byte2Mask) >>> 8;
		int ip4 = (ipMask & byte1Mask);
		int[] ipsSub = { ip1, ip2, ip3, ip4 };
		String[] ips = ip.split("\\.");
		String newIP = "";
		for (int i = 0; i < ips.length - 1; i++) {
			newIP += (Integer.parseInt(ips[i]) & ipsSub[i]) + ".";
		}
		newIP += (Integer.parseInt(ips[ips.length - 1]) & ipsSub[ips.length - 1]);
		return newIP;
	}

	/**
	 * @Desc 根据 ip 加 目标 ip 和 子网掩码 判断该ip是否属于该网段
	 * @param ip
	 * @param targetIp
	 * @param subnetMask
	 * @return true or flase
	 */
	public static boolean isBelongSegment(String ip, String targetIp, String subnetMask) {
		String cidr = targetIp + "/" + maskStr2InetMask(subnetMask);
		String[] ips = ip.split("\\.");
		int ipAddr = (Integer.parseInt(ips[0]) << 24) | (Integer.parseInt(ips[1]) << 16)
				| (Integer.parseInt(ips[2]) << 8) | Integer.parseInt(ips[3]);
		int type = Integer.parseInt(cidr.replaceAll(".*/", ""));
		int mask = 0xFFFFFFFF << (32 - type);
		String cidrIp = cidr.replaceAll("/.*", "");
		String[] cidrIps = cidrIp.split("\\.");
		int cidrIpAddr = (Integer.parseInt(cidrIps[0]) << 24) | (Integer.parseInt(cidrIps[1]) << 16)
				| (Integer.parseInt(cidrIps[2]) << 8) | Integer.parseInt(cidrIps[3]);

		return (ipAddr & mask) == (cidrIpAddr & mask);
	}

	public static String getIpAddr(HttpServletRequest request) {
		if (request == null) {
			return "unknown";
		}
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("X-Forwarded-For");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("X-Real-IP");
		}

		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}
	
	public static StringBuffer toBin(int x) {
		StringBuffer result = new StringBuffer();
		result.append(x % 2);
		x /= 2;
		while (x > 0) {
			result.append(x % 2);
			x /= 2;
		}
		return result;
	}

	public static int maskStr2InetMask(String maskStr) {
		StringBuffer sb;
		String str;
		int inetmask = 0;
		int count = 0;
		String[] ipSegment = maskStr.split("\\.");
		for (int n = 0; n < ipSegment.length; n++) {
			sb = toBin(Integer.parseInt(ipSegment[n]));
			str = sb.reverse().toString();
			count = 0;
			for (int i = 0; i < str.length(); i++) {
				i = str.indexOf("1", i);
				if (i == -1) {
					break;
				}
				count++;
			}
			inetmask += count;
		}
		return inetmask;
	}

}
